home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2000 February / Macworld (2000-02).dmg / Cool Extras! / WallBall Screen Saver / WallBall.dxr / 00007_Collision Detection.ls < prev    next >
Encoding:
Text File  |  1999-11-11  |  6.0 KB  |  145 lines

  1. property spriteNum, myTestMode, ourID, mySpriteList, mySpriteCount, myIntersectList, myCollisionList
  2.  
  3. on getBehaviorDescription me
  4.   return "COLLISION DETECTION" & RETURN & RETURN & "This behavior detects when the current sprite intersects other sprites." & RETURN & RETURN & "TIP: Use matte ink to limit intersection to the visible area of the sprite.  (This does not work with all member types)." & RETURN & RETURN & "You can choose whether to test for intersection with all sprites or only a certain selection.  In this way, you can make some sprites mutually 'invisible'." & RETURN & RETURN & "This behavior broadcasts a 'Collision_NewsFlash' message whenever the current sprite collides with another in the selected group." & RETURN & RETURN & "You can discover which sprites this sprite currently intersects by sending a '#Collision_GetIntersectList' message." & RETURN & RETURN & "PERMITTED MEMBER TYPES:" & RETURN & "Any visible members" & RETURN & RETURN & "PARAMETERS:" & RETURN & "* Test mode:" & RETURN & "  - all sprites " & RETURN & "  - all current sprites " & RETURN & "  - sprites in lower channels" & RETURN & "  - current sprites in lower channels" & RETURN & "  - sprites with the same behavior in lower channels" & RETURN & "  - sprites with the same ID in lower channels" & RETURN & "* Optional ID for this group" & RETURN & RETURN & "You can make certain sprites 'invisible' to certain others by assigning them different IDs, and choosing the 'ID' test mode for both.  Or you can choose the 'current sprites' test mode and start the 'invisible' sprites in a later frame." & RETURN & RETURN & "Mixing test modes on different sprites can lead to interesting results." & RETURN & RETURN & "Do not use the 'all sprites' or the 'all current sprites' modes on more than one sprite at a time.  If you do, BOTH sprites will send a 'Collision_NewsFlash' message when they collide." & RETURN & "Using the 'lower channels' options will generate just one message for each collision." & RETURN & RETURN & "ASSOCIATED BEHAVIORS:" & RETURN & "+ Motion vector" & RETURN & "+ Drag and toss"
  5. end
  6.  
  7. on getBehaviorTooltip me
  8.   vTip = "Use with any visible member types." & RETURN & RETURN
  9.   vTip = vTip & "Use matte ink (won't work with Flash or" & RETURN
  10.   vTip = vTip & "Vector shapes) to limit intersection" & RETURN
  11.   vTip = vTip & "and collision detection to the sprite's" & RETURN
  12.   vTip = vTip & "visible area."
  13.   return vTip
  14. end
  15.  
  16. on Collision_NewsFlash me, collisionList
  17.   sendSprite(100, #bounce, collisionList)
  18. end
  19.  
  20. on beginSprite me
  21.   Initialize(me)
  22. end
  23.  
  24. on prepareFrame me
  25.   CheckIntersects(me)
  26. end
  27.  
  28. on Initialize me
  29.   mySpriteList = []
  30.   myIntersectList = []
  31.   myCollisionList = []
  32.   case myTestMode of
  33.     "all sprites":
  34.       repeat with theSprite = 1 to the lastChannel
  35.         mySpriteList.append(theSprite)
  36.       end repeat
  37.       mySpriteList.deleteOne(spriteNum)
  38.     "all current sprites":
  39.       repeat with theSprite = 1 to the lastChannel
  40.         if sprite(theSprite).member <> #empty then
  41.           mySpriteList.append(theSprite)
  42.         end if
  43.       end repeat
  44.       mySpriteList.deleteOne(spriteNum)
  45.     "sprites in lower channels":
  46.       lastSprite = spriteNum - 1
  47.       repeat with theSprite = 1 to lastSprite
  48.         mySpriteList.append(theSprite)
  49.       end repeat
  50.     "current sprites in lower channels":
  51.       lastSprite = spriteNum - 1
  52.       repeat with theSprite = 1 to lastSprite
  53.         if sprite(theSprite).member <> #empty then
  54.           mySpriteList.append(theSprite)
  55.         end if
  56.       end repeat
  57.     "sprites with this behavior in lower channels":
  58.       sendAllSprites(#Collision_GetSpriteList, mySpriteList, spriteNum)
  59.     "sprites with this ID in lower channels":
  60.       sendAllSprites(#Collision_GetSpriteList, mySpriteList, spriteNum, ourID)
  61.   end case
  62.   mySpriteCount = mySpriteList.count()
  63. end
  64.  
  65. on CheckIntersects me
  66.   intersectList = []
  67.   i = mySpriteCount
  68.   repeat while i
  69.     otherSprite = mySpriteList[i]
  70.     if sprite spriteNum intersects otherSprite then
  71.       intersectList.append(otherSprite)
  72.     end if
  73.     i = i - 1
  74.   end repeat
  75.   CheckCollisions(me, intersectList)
  76. end
  77.  
  78. on CheckCollisions me, intersectList
  79.   myCollisionList = duplicate(intersectList)
  80.   i = myCollisionList.count
  81.   repeat while i
  82.     touchingSprite = myCollisionList[i]
  83.     alreadyTouching = myIntersectList.getPos(touchingSprite)
  84.     if alreadyTouching then
  85.       myCollisionList.deleteAt(i)
  86.     end if
  87.     i = i - 1
  88.   end repeat
  89.   myIntersectList = intersectList
  90.   if myCollisionList.count then
  91.     NewCollision(me)
  92.   end if
  93. end
  94.  
  95. on NewCollision me
  96.   i = myCollisionList.count
  97.   repeat while i
  98.     collidingSprite = myCollisionList[i]
  99.     sendAllSprites(#Collision_NewsFlash, [collidingSprite, spriteNum])
  100.     i = i - 1
  101.   end repeat
  102. end
  103.  
  104. on Collision_GetSpriteList me, theList, callingSpriteNum, theID
  105.   if stringp(theID) then
  106.     if theID <> ourID then
  107.       exit
  108.     end if
  109.   end if
  110.   if callingSpriteNum = spriteNum then
  111.     exit
  112.   end if
  113.   if mySpriteList.getPos(callingSpriteNum) then
  114.     exit
  115.   end if
  116.   theList.append(spriteNum)
  117. end
  118.  
  119. on Collision_GetIntersectList me, theList
  120.   if listp(theList) then
  121.     if theList.ilk(#propList) then
  122.       i = myIntersectList.count()
  123.       repeat while i
  124.         touchingSprite = myIntersectList[i]
  125.         theList.addProp(spriteNum, touchingSprite)
  126.         i = i - 1
  127.       end repeat
  128.     else
  129.       i = myIntersectList.count()
  130.       repeat while i
  131.         touchingSprite = myIntersectList[i]
  132.         theList.append([spriteNum, touchingSprite])
  133.         i = i - 1
  134.       end repeat
  135.     end if
  136.   else
  137.     return myIntersectList
  138.   end if
  139.   return theList
  140. end
  141.  
  142. on getPropertyDescriptionList me
  143.   return [#myTestMode: [#comment: "Check for collisions with", #format: #string, #range: ["all sprites", "all current sprites", "sprites in lower channels", "current sprites in lower channels", "sprites with this behavior in lower channels", "sprites with this ID in lower channels"], #default: "all sprites in lower channels"], #ourID: [#comment: "Unique ID for this group (optional):", #format: #string, #default: "ID " & the currentSpriteNum]]
  144. end
  145.